package com.hejjon.knowledgebase.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hejjon.knowledgebase.constant.MessageConstant;
import com.hejjon.knowledgebase.constant.event.EventKeys;
import com.hejjon.knowledgebase.entity.RepairRecord;
import com.hejjon.knowledgebase.exception.BusinessException;
import com.hejjon.knowledgebase.mapper.RepairRecordMapper;
import com.hejjon.knowledgebase.model.request.RepairRecordRequest;
import com.hejjon.knowledgebase.model.wrapper.DataGrid;
import com.hejjon.knowledgebase.service.RepairRecordService;
import com.hejjon.knowledgebase.util.BeanMapUtil;
import com.hejjon.knowledgebase.util.EventParamsHolder;
import com.hejjon.knowledgebase.util.Valid;
import com.hejjon.knowledgebase.vo.RepairRecordVO;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备报修日志表 服务实现类
 * </p>
 *
 * @author caoshi
 * @since 2022-12-13
 */
@Service
public class RepairRecordServiceImpl implements RepairRecordService {

    @Resource
    private RepairRecordMapper repairRecordMapper;


    @Override
    public Long addRepairRecord(RepairRecordRequest request) {

        RepairRecord insert = new RepairRecord();
        insert.setDeviceName(request.getDeviceName());
        insert.setRepairman(request.getRepairman());
        insert.setPhone(request.getPhone());
        insert.setBuilding(request.getBuilding());
        insert.setClassroom(request.getClassroom());
        insert.setContent(request.getContent());
        insert.setRepairEndTime(request.getRepairEndTime());
        insert.setState(request.getState());
        insert.setCreateTime(LocalDateTime.now());

        this.repairRecordMapper.insert(insert);

        // 设置日志参数
        EventParamsHolder.addParams(BeanMapUtil.bean2Map(insert));
        EventParamsHolder.addParam(EventKeys.NAME, insert.getDeviceName());
        return insert.getId();
    }

    @Override
    public Integer deleteRepairRecord(List<Long> idList) {
        int effect = 0;
        for (Long id : idList) {
            effect += this.repairRecordMapper.deleteById(id);
        }

        // 设置日志参数
        EventParamsHolder.addParam(EventKeys.ID_LIST, idList);
        EventParamsHolder.addParam(EventKeys.COUNT, effect);
        return effect;
    }


    @Override
    public Integer updateRepairRecord(RepairRecordRequest request) {

        Long id = request.getId();
        RepairRecord repairRecord = this.repairRecordMapper.selectById(id);
        Valid.notNull(repairRecord, MessageConstant.UNKNOWN_DATA);

        RepairRecord update = new RepairRecord();
        update.setId(id);
        update.setDeviceName(request.getDeviceName());
        update.setRepairman(request.getRepairman());
        update.setPhone(request.getPhone());
        update.setBuilding(request.getBuilding());
        update.setClassroom(request.getClassroom());
        update.setContent(request.getContent());
        update.setRepairEndTime(request.getRepairEndTime());
        update.setState(request.getState());
        update.setUpdateTime(LocalDateTime.now());
        int effect = this.repairRecordMapper.updateById(update);

        // 日志参数
        EventParamsHolder.addParams(BeanMapUtil.bean2Map(update));
        EventParamsHolder.addParam(EventKeys.NAME, update.getDeviceName());
        return effect;
    }

    @Override
    public DataGrid<RepairRecordVO> listRepairRecord(RepairRecordRequest request) {
        Page<RepairRecord> page = new Page<>(request.getPage(), request.getLimit());

        LambdaQueryWrapper<RepairRecord> wrapper = new LambdaQueryWrapper<RepairRecord>()
                .eq(request.getState() != null, RepairRecord::getState, request.getState())
                .like(StringUtils.isNotBlank(request.getDeviceName()), RepairRecord::getDeviceName, request.getDeviceName())
                .like(StringUtils.isNotBlank(request.getRepairman()), RepairRecord::getRepairman, request.getRepairman())
                .like(StringUtils.isNotBlank(request.getBuilding()), RepairRecord::getBuilding, request.getBuilding())
                .like(StringUtils.isNotBlank(request.getClassroom()), RepairRecord::getClassroom, request.getClassroom())
                .orderByDesc(RepairRecord::getCreateTime);

        Page<RepairRecord> repairRecordPage = this.repairRecordMapper.selectPage(page, wrapper);
        Page<RepairRecordVO> voPage = new Page<>();
        voPage.setSize(repairRecordPage.getSize());
        voPage.setCurrent(repairRecordPage.getCurrent());
        voPage.setPages(repairRecordPage.getPages());
        voPage.setTotal(repairRecordPage.getTotal());
        List<RepairRecord> records = repairRecordPage.getRecords();
        List<RepairRecordVO> voRecords = new ArrayList<>();
        try {
            for (RepairRecord repairRecord : records) {
                RepairRecordVO vo = new RepairRecordVO();
                BeanUtils.copyProperties(vo, repairRecord);
                voRecords.add(vo);
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new BusinessException(MessageConstant.PARSE_ERROR);
        }
        voPage.setRecords(voRecords);
        return DataGrid.of(voPage);
    }

    @Override
    public RepairRecordVO getRepairRecord(Long id) {

        RepairRecord repairRecord = this.repairRecordMapper.selectById(id);
        if (repairRecord == null) {
            throw new BusinessException(MessageConstant.UNKNOWN_DATA);
        }
        RepairRecordVO vo = new RepairRecordVO();
        try {
            BeanUtils.copyProperties(vo, repairRecord);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new BusinessException(MessageConstant.OPERATOR_ERROR);
        }

        return vo;
    }

    @Override
    public Map<Integer, List<RepairRecord>> getRecordByState() {
        List<RepairRecord> repairRecords = this.repairRecordMapper.selectList(null);
        Valid.notEmpty(repairRecords, MessageConstant.UNKNOWN_DATA);
        return repairRecords.stream().collect(Collectors.groupingBy(RepairRecord::getState));
    }
}
